package ibmmodel3;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author mwh
 */
public class TranslationTableMem implements TranslationTable {

    public final Map<Integer, Map<Integer, Double>> table;



    public Iterator<Integer> keyIterator() {
        return table.keySet().iterator();
    }
    
    public TranslationTableMem(String filename) throws FileNotFoundException, IOException {

        table = new HashMap<Integer, Map<Integer, Double>>();

        BufferedReader input = new BufferedReader(new FileReader(filename));
        String line;
        while ((line = input.readLine()) != null) {

            String[] tokens = line.split(" ");

            Integer source = Integer.parseInt(tokens[0]);
            Integer target = Integer.parseInt(tokens[1]);
            Double prob = Double.parseDouble(tokens[2]);

            Map<Integer, Double> sourceMap;
            if (table.containsKey(source)) {
                sourceMap = table.get(source);
            } else {
                sourceMap = new HashMap<Integer, Double>();
                table.put(source, sourceMap);
            }
            sourceMap.put(target, prob);

        }

        simpleSmooth();
    }


    /*
     * A simple self-made smoothing procedure.
     * A unknown translation is assigned half the probability of the lest likely known translation
     * The probability mass for the unknown translation is subtracted uniformly from the known translations.
     */
    private void simpleSmooth() {
   
        for (Integer s : table.keySet()) {
            Map<Integer, Double> translations = table.get(s);
            Double min = Double.POSITIVE_INFINITY;
            // Find translation with lowest probability
            for (Integer t : translations.keySet()) {
                min = Math.min(min, translations.get(t));
            }

            double unkProb = 0.5 * min;
            translations.put(-1024, unkProb);

            // Subtract prob-mass uniformly from known translations.
            double subProb = unkProb / translations.size();
            for (Integer t : translations.keySet()) {
                translations.put(t, translations.get(t) - subProb);
            }

        }

    }

    public Map<Integer, Double> get(Integer source) {
        return table.get(source);
    }

    public double get(Integer source, Integer target) {
        if (table.containsKey(source)) {
            if (table.get(source).containsKey(target)) {
                return table.get(source).get(target);
            }
            return table.get(source).get(-1024);
        }
        return Double.NaN;
    }


    public double getLog10(int source, int target) {
        return Math.log10(get(source, target));
    }
}
